package com.zq.springadmin.service.impl;

import com.zq.springadmin.properties.MinioProperties;
import com.zq.springadmin.service.MinioService;
import io.minio.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class MinioServiceImpl implements MinioService {
    @Resource
    private MinioClient minioClient;

    @Resource
    private MinioProperties minioProperties;

    /*
     * 上传文件
     * */
    @Override
    public String uploadFile(MultipartFile file) {
        try {
//判断桶是否存在
            boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
            if (!bucketExists){
//                如果不存在，就创建桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
            }
//            本地时间，具体到年、月、日
            String yyyymmdd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//            String uuid= UUID.randomUUID().toString();
            String filename = yyyymmdd+"/"+file.getOriginalFilename();
//          加一个/表示创建一个文件夹
            minioClient.putObject(PutObjectArgs.builder().
                    bucket(minioProperties.getBucketName()).
                    object(filename).
                    stream(file.getInputStream(), file.getSize(), -1).
//                    文件上传的类型，如果不指定，那么每次访问时都要先下载文件
        contentType(file.getContentType()).
                    build());
            String url= minioProperties.getUrl()+"/"+ minioProperties.getBucketName()+"/"+filename;
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件上传失败");
        }
    }

    /*
     * 根据url 下载文件
     * */
    @Override
    public String getObject(HttpServletRequest request, HttpServletResponse response, String url){
//        将传递的url 进行切割，获取到相对于桶的文件名
        String objectUrl = url.split(minioProperties.getBucketName()+"/")[1];
//        文件名
        String fileName = objectUrl.split("/")[1];
        // 设置响应的内容类型为文件类型
        response.setContentType("application/octet-stream");
        // 设置响应头，指定文件名
        response.setHeader("Content-Disposition", "attachment; filename=\"filename.extension\"");
        // 缓冲区大小
        byte[] buffer = new byte[1024];
        int bytesRead;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try{
            inputStream = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(objectUrl)
                    .build());
         /*   // 将输入流的内容复制到一个文件中
            String filePath = "D://"+fileName;
            Files.copy(inputStream, Path.of(filePath),
                    StandardCopyOption.REPLACE_EXISTING);
            return "文件下载成功，地址为"+filePath;*/
            // 获取输出流
            outputStream = response.getOutputStream();
            // 将输入流中的数据写入输出流
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            inputStream.close();
            outputStream.close();

        }catch (Exception e){
            e.printStackTrace();
        }
        return "文件下载失败";
    }

    /*
     * 根据url删除文件
     * */
    @Override
    public void deleteFile(String url) {
        //        将传递的url 进行切割，获取到相对于桶的文件名
        String objectUrl = url.split(minioProperties.getBucketName()+"/")[1];
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(objectUrl)
                    .build());

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(url+"文件删除失败");
        }
    }
}
